#include <stdio.h>
#include <vmath.h>
#include <scene.h>
#include <rt.h>

#define VER_MAJOR	0
#define VER_MINOR	1

void plugin_info(FILE *fp)
{
	fprintf(fp, "phong plugin (shader) v%d.%d\n", VER_MAJOR, VER_MINOR);
	fprintf(fp, "  author: Ioannis Tsiombikas <nuclear@member.fsf.org>\n");
	fprintf(fp, "  description: implements the phong reflectance model.\n");
}

vec4_t shade(ray_t ray, struct isect_point *is, struct material *mat, struct scene *scn)
{
	int i, do_spec, lt_count = scn_light_count(scn);
	vec4_t kd, ks, col = {0, 0, 0, 1};
	vec3_t vref;
	double shin;

	kd = mat_attr_value(mat, "diffuse", is->texcoords, v4_cons(1, 1, 1, 1));
	ks = mat_attr_value(mat, "specular", is->texcoords, v4_cons(0, 0, 0, 0));
	shin = mat_attr_value(mat, "shininess", is->texcoords, v4_cons(20, 0, 0, 0)).x;

	do_spec = ks.x > 0.0 && ks.y > 0.0 && ks.z > 0.0;

	vref = v3_normalize(v3_reflect(ray.dir, is->normal));

	for(i=0; i<lt_count; i++) {
		float ndotl, rdotl;
		struct light *lt = scn_light(scn, i);
		vec4_t lcol;
		vec3_t lpos, ldir;
		ray_t sray;

		lpos = lt_get_point(lt);
		ldir = v3_sub(lpos, is->pos);

		sray.origin = is->pos;
		sray.dir = ldir;

		if(ray_test(scn, sray, 0)) {
			continue;
		}
		
		lcol = lt_get_color_att(lt, is->pos);
		
		ldir = v3_normalize(ldir);
		ndotl = MAX(v3_dot(is->normal, ldir), 0.0);

		col.x += kd.x * ndotl * lcol.x;
		col.y += kd.y * ndotl * lcol.y;
		col.z += kd.z * ndotl * lcol.z;

		if(do_spec) {
			rdotl = pow(MAX(v3_dot(vref, ldir), 0.0), shin);
			col.x += ks.x * rdotl * lcol.x;
			col.y += ks.y * rdotl * lcol.y;
			col.z += ks.z * rdotl * lcol.z;
		}
	}
	return col;
}
